<?php
// class generator to send a searching request to a given website then take back the loads
class VentepriveeGenerator
{
	protected $config_id;
	protected $jobboard_name;
	protected $items= array();
	protected $client;
	
	public function __construct($config_id, $jobboard_name)
	{
		$this->config_id = $config_id;
		$this->jobboard_name = $jobboard_name;
	}
	

	private function create_log($filename, $content) {
		//$file = dirname(dirname(dirname(dirname(__FILE__)))).'/log/'.$filename;
		//file_put_contents($file, $content);
	}
	
	
	private function initialize()
	{
	    // TOTO make it to a sfconfig get
	}
	
	
	private function mapping($value, $mapping)
	{
		if (array_key_exists($value, $mapping))
			return $mapping[$value];
		else return null;
	}
	
	
	public function execute()
	{
		$this->initialize();
		$this->client = new WebFormClient();
		
		$is_oneday_active = false;
		$this->client->setLogPrefix(dirname(dirname(dirname(dirname(__FILE__)))).'/log/'.$this->jobboard_name.' '.date("Y-m-d H-i-s O", time()));
		
		$jobboard = Doctrine_Core::getTable('Jobboard')->findOneByName($this->jobboard_name);
		if (!$jobboard) {
			$notify_error = new NotifyError("Vente Privée - Jobboard not found\n");
			$notify_error->execute();
			return;
		}
		
		//try {
			// ok everything is ready, lets go
		$tag = array();
		$base_url = $jobboard->address;
		$this->client->get($base_url);
		$this->client->load(array('id' => 'aspnet_form'));
		        $this->client->validate(array(
		                '__VIEWSTATE'       => 'input-hidden',
		                '__EVENTVALIDATION' => 'input-hidden',
		                'txtEmail'          => 'input-text',
		                'txtPassword'       => 'input-password',
		                'btSubmit'          => 'input-submit',
		                ));
		$tag['login'] = $this->client->getData();
		
		// login step
		$first_account = $jobboard->Accounts;
		foreach ($jobboard->Accounts as $account) 
			if ($account->is_active) {
				$first_account = $account;
				break;
			}
		$tag['login']['txtEmail'] = $first_account->username;
		$tag['login']['txtPassword'] = $first_account->password;
		$tag['login']['btSubmit'] = 'OK';
		$this->client->fill($tag['login']);
		$this->client->post('https://secure.fr.vente-privee.com/vp4/Login/Portal_FR.aspx');
		
		// parsing list of current vente
		$doc = new DOMDocument();
		@$doc->loadHTML($this->client->getBody());
		$xpath = new DOMXpath($doc);

		$nodes = $xpath->query('//*[@class="currentlySalesWrap"]/ul/li');
		foreach ($nodes as $node) {
			$li = $xpath->query('div/a/h4', $node);
			foreach ($li as $a) {
				$marque = trim($a->nodeValue);
				break;
			}
			if (!(!$is_oneday_active && preg_match("#One Day#", $marque, $match))) { 
				$li = $xpath->query('div/a', $node);
				foreach ($li as $a) 
					foreach ($a->attributes as $attribute)
						if ($attribute->name == 'href') {
							$this->items[$marque]['href'] = "http://fr.vente-privee.com".$attribute->value;
							preg_match('/operationid=([\d]*)/', $attribute->value, $match);
							$this->items[$marque]['id'] = $match[1];
							$parent_div = $a->parentNode;
							$img_link = $parent_div->getAttribute("style");
							preg_match("#background-image:url\(([^\)]*)#", $img_link, $match);
							$this->items[$marque]['logo'] = "http://fr.vente-privee.com".$match[1];
						}
			}
		}

		// parsing each marque
		$executed_count = 0;
		foreach ($this->items as $marque => $data) 
			if ($executed_count < 20 && !Marque::is_restricted($jobboard->id, $marque) && isset($data['id']) && !Marque::is_full_import($data['id'])) {
				$executed_count++;
				echo "GET ".$marque.": ".$data['href']."\n";
				
				if (Marque::is_new($data['id'])) {
					$marque_obj = new Marque();
					$marque_obj->id = $data['id'];
					$marque_obj->jobboard_id = $jobboard->id;
					$marque_obj->name = $marque;
					$marque_obj->logo = $data['logo'];
					$marque_obj->href = $data['href'];
					$marque_obj->save();
					echo "CREATING Marque: ".$marque."\n";

					// here create category associating to this marque
					$category = new Category();
					$category->name = $marque_obj->name;
					$category->parent_id = 1; // fix to home category
					$category->description = "Category for marque ".$marque_obj->name;
					$category->image = $marque_obj->logo;
					$category->href = $marque_obj->href;
					$category->is_active = true;
					$category->save();
					$marque_obj->category_id = $category->id;
					$marque_obj->save();
				} else {
					$marque_obj = Doctrine_Core::getTable('Marque')->find($data['id']);
					echo "RESUMING Marque: ".$marque."\n";
				}
				
			
				$this->client->get($data['href']);
				$doc = new DOMDocument();
				@$doc->loadHTML($this->client->getBody());
				$xpath = new DOMXpath($doc);
				
				$catalogs = $xpath->query('//*[@id="altCol"]/div/div[1]/ul/li');
				foreach ($catalogs as $catalog) {
					if (preg_match('/brandLogo/', $catalog->getAttribute('id'), $match)) { // it's a little logo
						foreach ($catalog->childNodes as $child)
								if ($child->nodeName == "a")
									foreach ($child->childNodes as $img)
										if ($img->nodeName == "img")			
											$marque_obj->little_logo = "http://fr.vente-privee.com".$img->getAttribute('src');
						$marque_obj->save();
					}
					
					if (preg_match('/liUniverse/', $catalog->getAttribute('id'), $match)) { // first level sup-category
						$first_sub_cat = new Category();
						$first_sub_cat->parent_id = $category->id;
						foreach ($catalog->childNodes as $child)
							if ($child->nodeName == "a") {
								$first_sub_cat->href = "http://fr.vente-privee.com".$child->getAttribute('href');
								foreach ($child->childNodes as $span)
									if ($span->nodeName == "span")
										$first_sub_cat->name = $span->nodeValue;
							}
						
						if (!$first_sub_cat_temp = Doctrine_Core::getTable('Category')->findOneByNameAndParentId($first_sub_cat->name, $first_sub_cat->parent_id)) {
							$first_sub_cat->save();
							echo "CREATING first category: ".$first_sub_cat->name." with Id: ".$first_sub_cat->id."\n";
						} else {
							$first_sub_cat = $first_sub_cat_temp;
							echo "RESUMING first category: ".$first_sub_cat_temp->name." with Id: ".$first_sub_cat_temp->id."\n";
						}

						$this->client->get($first_sub_cat->href);
						$doc_category = new DOMDocument();
						@$doc_category->loadHTML($this->client->getBody());
						$xpath = new DOMXpath($doc_category);

						$brands = $xpath->query('//*[@class="subMenuEV"]/li');
						if ($brands->length == 0) { // 1st level category doesn't have sub-category, associates directlly to products
							$second_sub_cat = new Category();
							$second_sub_cat->name = "Product";
							$second_sub_cat->parent_id = $first_sub_cat->id;
							if (!$second_sub_cat_temp = Doctrine_Core::getTable('Category')->findOneByNameAndParentId("Product", $second_sub_cat->parent_id)) {
								$second_sub_cat->save();
								echo "CREATING default product category with Id: ".$second_sub_cat->id."\n";
							} else {
								$second_sub_cat = $second_sub_cat_temp;
								echo "RESUMING default production category with Id: ".$second_sub_cat->id."\n";
							}
							$this->create_product($this->client->getBody(), $second_sub_cat, $marque);
						} else {
							foreach ($brands as $brand) 
								if (!preg_match('/liUniverseViewAll/', $brand->getAttribute('id'), $match)) { // 2nd level sup-category
									$second_sub_cat = new Category();
									foreach ($brand->childNodes as $node)
										if ($node->nodeName == "a") {
											$second_sub_cat->name = trim($node->nodeValue);
											$second_sub_cat->href = "http://fr.vente-privee.com".$node->getAttribute('href');
											$second_sub_cat->parent_id = $first_sub_cat->id;
										}
									if (!$second_sub_cat_temp = Doctrine_Core::getTable('Category')->findOneByNameAndParentId($second_sub_cat->name, $second_sub_cat->parent_id)) {
										$second_sub_cat->save();
										echo "CREATING second sub category: ".$second_sub_cat->name." with Id: ".$second_sub_cat->id."\n";
									} else {
										$second_sub_cat = $second_sub_cat_temp;
										echo "RESUMING second sub category: ".$second_sub_cat->name." with Id: ".$second_sub_cat->id."\n";
									}
									
									$this->client->get($second_sub_cat->href);
									$this->create_product($this->client->getBody(), $second_sub_cat, $marque);
								}
							}
					}
				}
			// we remarke those marques to full imported status
			$marque_obj->is_full_import = true;
			$marque_obj->save();	
		}
	}


	private function create_product($body, $product_category, $marque)
	{
		$doc_brand = new DOMDocument();
		//@$doc_brand->loadHTMLFile('/Applications/XAMPP/htdocs/ban-rieng/log/Venteprivee 2013-01-03 06-16-12 -0700-step6-response.html');
		@$doc_brand->loadHTML($body);
		$xpath = new DOMXpath($doc_brand);
		$products = $xpath->query('//*[@class="artList"]/li');
		$index = -1;
		foreach ($products as $product) 
			if (!preg_match('#Epuisé#', $product->nodeValue, $match)) {
				$index++;
				$this->items[$marque]['products'][$index] = $this->parseProduct($product);
				$product_obj = new Product();
				$product_obj->id = $this->items[$marque]['products'][$index]['id'];
				if (Product::is_new($product_obj->id) && $this->items[$marque]['products'][$index]['available']) {
					$product_obj->category_id = $product_category->id;
					$product_obj->name = $this->items[$marque]['products'][$index]['name'];
					$product_obj->discount_price = $this->items[$marque]['products'][$index]['prix_discount'];
					$product_obj->original_price = $this->items[$marque]['products'][$index]['prix_origin'];
					$product_obj->detail_link = $this->items[$marque]['products'][$index]['detail_link'];
					$product_obj->images = json_encode($this->items[$marque]['products'][$index]['images']);
					$product_obj->family_id = $this->items[$marque]['products'][$index]['family_id'];
					$product_obj->available = $this->items[$marque]['products'][$index]['available'];
					$product_obj->jobboard_name = $this->jobboard_name;
					$product_obj->marque_name = $marque;
					if (isset($this->items[$marque]['products'][$index]['product_id']))
						$product_obj->product_id = $this->items[$marque]['products'][$index]['product_id'];
					$product_obj->save();
					foreach ($this->items[$marque]['products'][$index]['options'] as $option) {
						$option_obj = new ProductOption();
						$option_obj->product_id = $product_obj->id;
						$option_obj->name = $option['name'];
						$option_obj->code = $option['code'];
						$option_obj->available = $option['available'];
						$option_obj->save();
					}
				}
		}
	}
	
	
	private function parseProduct($product)
	{
		$item = array();
		foreach ($product->childNodes as $info)
			if ($info->nodeName == "div") {
				if ($info->getAttribute('class') == 'infoArt')
					$info_art = $info;
				elseif ($info->getAttribute('class') == 'imgArt')
					$img_art = $info;
				elseif ($info->getAttribute('class') == 'btArt')
					$bt_art = $info;
			}
		// process info article
		foreach ($info_art->childNodes as $node) {
			if ($node->nodeName == "div" && $node->getAttribute('class') == "infoArtTitle") {  // process info name
				$item['name'] = trim($node->nodeValue);
				foreach ($node->childNodes as $a)
					if ($a->nodeName == "a" && $a->hasAttribute('name'))
						$item['id'] = $a->getAttribute('name');
			}	
			if ((Product::is_new($item['id'])) && ($node->nodeName == "div") && ($node->getAttribute('class') == "infoArtPrice")) { // process info price
				foreach ($node->childNodes as $span)
					if ($span->nodeName == "span" && $span->getAttribute('class') == "artPrice") { // discount price
						$item['prix_discount'] = htmlentities($span->nodeValue, ENT_QUOTES);
						$item['prix_discount'] = preg_replace('#[^\d^,]#', '', $item['prix_discount']);
						$item['prix_discount'] = str_replace(',', '.', $item['prix_discount']);
					} elseif ($span->nodeName == "span" && $span->getAttribute('class') == "artOldPrice") { // original price
						$item['prix_origin'] = htmlentities($span->nodeValue, ENT_QUOTES);
						$item['prix_origin'] = preg_replace('#[^\d^,]#', '', $item['prix_origin']);
						$item['prix_origin'] = str_replace(',', '.', $item['prix_origin']);
					} elseif ($span->nodeName == "span" && $span->getAttribute('class') == "artState") { // original state
						if ($span->nodeValue == "Encore disponible") {
							$item['available'] = true;
						} else {
							$item['available'] = false;
						}

					}
			}
		}

		foreach ($img_art->childNodes as $node)
			if ($node->nodeName == "a" && $node->hasAttribute('href')) { // process image article
				$item['detail_link'] = "http://fr.vente-privee.com".$node->getAttribute('href');
				foreach ($node->childNodes as $img)
					if ($img->nodeName == "img") {
						$base_image_url = "http://fr.vente-privee.com".$img->getAttribute('src');
						$images = array();
						$images['thumb'] = $base_image_url;
						$images['list'] = array();
						$index = 0;
						while ($index < 3) {
							$image_url = preg_replace('#products\/[^.]*#', 'products/fp_det'.$index.'_'.$item['id'], $base_image_url);
							$images['list'][] = $image_url;
							$index++;
						} 
						$item['images'] = $images;
					}

				// now we get in and take availibily for each option
					if ($item['available']) {
						$this->client->get($item['detail_link']);
						$product_doc = new DOMDocument();
						@$product_doc->loadHTML($this->client->getBody());
						$xpath = new DOMXpath($product_doc);
						$options = $xpath->query('//*[@id="productId"]/option[position()>1]');
						preg_match('/name="familyId" id="familyId" value="([^"]*)"/', $this->client->getBody(), $family_id);
						$family_id = $family_id[1];
						$item['family_id'] = $family_id; 
						$item['options'] = array();
						foreach ($options as $option) {
							$options_detail = array();
							$options_detail['name'] = trim($option->nodeValue);
							$options_detail['code'] = $option->getAttribute('value');
							$options_detail['available'] = preg_match('/dispo./', $option->nodeValue, $match) ? true : false;
							$item['options'][] = $options_detail;
						}
						if (empty($item['options'])) { // no option, take an only
							preg_match('/name="productId" value="([^"]*)"/', $this->client->getBody(), $product_id);
							$product_id = $product_id[1];
							$item['product_id'] = $product_id;
						}
					}
					
				}
		return $item;
	}
	
	
	public function getItems()
	{
		return $this->items;
	}
	
	
	private function get_more_info($body)
	{
		$infos = array();
		$doc = new DOMDocument();
		@$doc->loadHTML($body);
		//@$doc->loadHTMLFile('/Applications/XAMPP/htdocs/ban-rieng/log/Venteprivee 2012-12-16 00-58-47 -0700-step4-response.html');
		$xpath = new DOMXpath($doc);
		
		// take images set
		$images = $xpath->query('//*[@class="listMiniVisual"]/a');
		foreach ($images as $image) {
			$link = $image->firstChild->getAttribute('src');
			$link = "http://fr.vente-privee.com/".preg_replace('/det/', 'fp_det', $link);
			$infos['images'][] = $link;
		}
		
		// TODO take product's description
		$infos['detail'] = "";
		return $infos;
	}
}
?>